﻿using System;
using System.Text;
using System.Diagnostics;

using RaisingStudio.SmallProgram.Library.Internal;

namespace RaisingStudio.SmallProgram.Library
{
    [SmallProgramType]
    public static class TextWindow
    {
        private static bool _windowVisible;

        public static Primitive BackgroundColor
        {
            get
            {
                VerifyAccess();
                return Console.BackgroundColor.ToString();
            }
            set
            {
                VerifyAccess();
                try
                {
                    Console.BackgroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), (string)value, true);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                }
            }
        }

        public static Primitive ForegroundColor
        {
            get
            {
                VerifyAccess();
                return Console.ForegroundColor.ToString();
            }
            set
            {
                VerifyAccess();
                try
                {
                    Console.ForegroundColor = (ConsoleColor)Enum.Parse(typeof(ConsoleColor), (string)value, true);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                }
            }
        }

        public static Primitive Title
        {
            get
            {
                VerifyAccess();
                return new Primitive(Console.Title);
            }
            set
            {
                VerifyAccess();
                Console.Title = (string)value;
            }
        }

        public static Primitive Left
        {
            get
            {
                RECT rect;
                VerifyAccess();
                NativeHelper.GetWindowRect(NativeHelper.GetConsoleWindow(), out rect);
                return rect.Left;
            }
            set
            {
                RECT rect;
                VerifyAccess();
                IntPtr consoleWindow = NativeHelper.GetConsoleWindow();
                NativeHelper.GetWindowRect(consoleWindow, out rect);
                NativeHelper.SetWindowPos(consoleWindow, IntPtr.Zero, (int)value, rect.Top, 0, 0, 1);
            }
        }

        public static Primitive Top
        {
            get
            {
                RECT rect;
                VerifyAccess();
                NativeHelper.GetWindowRect(NativeHelper.GetConsoleWindow(), out rect);
                return rect.Top;
            }
            set
            {
                RECT rect;
                VerifyAccess();
                IntPtr consoleWindow = NativeHelper.GetConsoleWindow();
                NativeHelper.GetWindowRect(consoleWindow, out rect);
                NativeHelper.SetWindowPos(consoleWindow, IntPtr.Zero, rect.Left, (int)value, 0, 0, 1);
            }
        }

        public static Primitive CursorLeft
        {
            get
            {
                VerifyAccess();
                return new Primitive(Console.CursorLeft);
            }
            set
            {
                VerifyAccess();
                Console.CursorLeft = (int)value;
            }
        }

        public static Primitive CursorTop
        {
            get
            {
                VerifyAccess();
                return new Primitive(Console.CursorTop);
            }
            set
            {
                VerifyAccess();
                Console.CursorTop = (int)value;
            }
        }

        private static void VerifyAccess()
        {
            if (!_windowVisible)
            {
                Show();
            }
        }

        public static void Show()
        {
            if (!_windowVisible && NativeHelper.AllocConsole())
            {
                _windowVisible = true;
            }
        }

        public static void Hide()
        {
            if (_windowVisible && NativeHelper.FreeConsole())
            {
                _windowVisible = false;
            }
        }

        public static void Clear()
        {
            VerifyAccess();
            Console.Clear();
        }

        public static void Pause()
        {
            VerifyAccess();
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey(true);
        }

        public static void PauseIfVisible()
        {
            if (_windowVisible)
            {
                Pause();
            }
        }

        public static void PauseWithoutMessage()
        {
            VerifyAccess();
            Console.ReadKey(true);
        }


        public static Primitive Read()
        {
            VerifyAccess();
            return new Primitive(Console.ReadLine());
        }

        [HideFromIntellisense]
        public static Primitive ReadKey()
        {
            VerifyAccess();
            return new string(Console.ReadKey(true).KeyChar, 1);
        }

        public static Primitive ReadNumber()
        {
            TextWindow.VerifyAccess();
            StringBuilder stringBuilder = new StringBuilder();
            bool flag = false;
            int num = 0;
            while (true)
            {
                ConsoleKeyInfo consoleKeyInfo = Console.ReadKey(true);
                char c = consoleKeyInfo.KeyChar;
                bool flag2 = false;
                if (c == '-' && num == 0)
                {
                    flag2 = true;
                }
                else
                {
                    if (c == '.' && !flag)
                    {
                        flag = true;
                        flag2 = true;
                    }
                    else
                    {
                        if (c >= '0' && c <= '9')
                        {
                            flag2 = true;
                        }
                    }
                }
                if (flag2)
                {
                    Console.Write(c);
                    stringBuilder.Append(c);
                    num++;
                }
                else
                {
                    if (num > 0 && consoleKeyInfo.Key == ConsoleKey.Backspace)
                    {
                        Console.CursorLeft--;
                        Console.Write(" ");
                        Console.CursorLeft--;
                        num--;
                        c = stringBuilder[num];
                        if (c == '.')
                        {
                            flag = false;
                        }
                        stringBuilder.Remove(num, 1);
                    }
                    else
                    {
                        if (consoleKeyInfo.Key == ConsoleKey.Enter)
                        {
                            break;
                        }
                    }
                }
            }
            Console.WriteLine();
            if (stringBuilder.Length == 0)
            {
                return new Primitive(0);
            }
            return new Primitive(stringBuilder.ToString());
        }


        public static void Write(Primitive data)
        {
            VerifyAccess();
            Console.Write((string)data);
        }

        public static void WriteLine(Primitive data)
        {
            VerifyAccess();
            Console.WriteLine((string)data);
        }
    }
}

